TypeScript 50.6%
JavaScript 46.1%
SQL 2.1%
Shell 0.6%
CSS 0.5%
1import { NextRequest, NextResponse } from "next/server";2import { createReadStream, existsSync, statSync } from "node:fs";3import path from "node:path";4import { STORAGE_DIR } from "@/lib/listings/media";5export const dynamic = "force-dynamic";6/** Sert les variantes WebP depuis le stockage local (clé validée, pas de traversée de répertoire). */7export async function GET(_req: NextRequest, { params }: { params: Promise<{ key: string[] }> }) {8 const { key } = await params;9 if (key.length !== 3 || !/^\d{4}-\d{2}$/.test(key[0]) || !/^[a-f0-9]{24}$/.test(key[1]) || !/^(1600|800|320)\.webp$/.test(key[2])) return new NextResponse("Not found", { status: 404 });10 const p = path.join(STORAGE_DIR, key[0], key[1], key[2]); if (!p.startsWith(STORAGE_DIR) || !existsSync(/*turbopackIgnore: true*/ p)) return new NextResponse("Not found", { status: 404 });11 const size = statSync(p).size;12 const stream = createReadStream(p);13 return new NextResponse(stream as unknown as ReadableStream, { headers: { "content-type": "image/webp", "content-length": String(size), "cache-control": "public, max-age=31536000, immutable" } });14}15